package com.xqboss.apps.service.user;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xqboss.apps.domain.punch.PunchUserSlot;
import com.xqboss.apps.domain.user.UserIdentityRankSlot;
import com.xqboss.apps.dto.punch.UserPunchSlotDto;
import com.xqboss.apps.enums.user.*;
import com.xqboss.apps.mapper.user.UserIdentityRankSlotMapper;
import com.xqboss.apps.service.punch.PunchUserSlotService;
import com.xqboss.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * <p>
 * 用户身份等级-多卡槽配置 服务实现类
 * </p>
 *
 * @author 木鱼
 * @since 2024-03-18
 */
@Service
@Slf4j
public class UserIdentityRankSlotService extends ServiceImpl<UserIdentityRankSlotMapper, UserIdentityRankSlot> {

    @Autowired
    private PunchUserSlotService punchUserSlotService;
    @Autowired
    private SysUserWalletService sysUserWalletService;
    @Autowired
    private UserAssetWrenchRecordService userAssetWrenchRecordService;
    @Autowired
    private UserAssetLidouService userAssetLidouService;

    /**
     * 解锁卡槽
     * @param userId
     * @param dto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean unlock(Long userId, UserPunchSlotDto dto) {
        // 检查用户卡槽是否存在
        PunchUserSlot userSlot = punchUserSlotService.selectSlotByUserIdAndSlotId(userId, dto.getSlotId());
        if (Objects.isNull(userSlot)) {
            throw new ServiceException("用户卡槽不存在");
        }
        if (!userSlot.getUserId().equals(userId)) {
            throw new ServiceException("卡槽不属于当前用户");
        }
        // 原始卡槽信息
        UserIdentityRankSlot slot = getById(dto.getSlotId());
        if (Objects.isNull(slot)) {
            throw new ServiceException("原始卡槽不存在");
        }
        // 如果配置热豆不为空并且大于0，校验用户热豆是否足够
        if (slot.getHotBeans() != null && slot.getHotBeans().compareTo(BigDecimal.ZERO) > 0) {
            // 扣除用户热豆
            sysUserWalletService.reduce(userId, UserWalletEnum.INTEGRAL, slot.getHotBeans(), WalletChangeTypeEnum.UNLOCK_SLOT, slot.getId(), WalletChangeTypeEnum.UNLOCK_SLOT.getMsg());
        }
        // 如果配置扳手不为空并且大于0，校验用户扳手是否足够
        if (slot.getWrench() != null && slot.getWrench().compareTo(BigDecimal.ZERO) > 0) {
            // 扣除用户扳手
            userAssetWrenchRecordService.updateWrenchBalance(userId, WalletWrenchChangeTypeEnum.UNLOCK_SLOT, WalletChangeDirectionEnum.OUT, slot.getWrench(), slot.getId(), WalletWrenchChangeTypeEnum.UNLOCK_SLOT.getMsg());
        }
        // 如果配置力豆不为空并且大于0，校验用户力豆是否足够
        if (slot.getLidou() != null && slot.getLidou().compareTo(BigDecimal.ZERO) > 0) {
            // 扣除用户力豆
            userAssetLidouService.updateLidouBalance(userId, WalletLidouChangeTypeEnum.UNLOCK_SLOT, WalletChangeDirectionEnum.OUT, slot.getLidou(), slot.getId(), WalletLidouChangeTypeEnum.UNLOCK_SLOT.getMsg());
        }
        PunchUserSlot updateSlot = new PunchUserSlot();
        updateSlot.setId(userSlot.getId());
        // 解锁
        if (dto.getType() == 0) {
            if (userSlot.getStatus() != -1) {
                throw new ServiceException("卡槽已解锁");
            }
            updateSlot.setStatus(0);
        } else if (dto.getType() == 1) {
            // 如果卡槽的过期时间字段为空说明卡槽为永久卡槽
            if (Objects.isNull(userSlot.getExpireTime())) {
                throw new ServiceException("卡槽为永久卡槽");
            }
            // 如果用户卡槽expireTime已经过期了，则从当前时间开始计算加上系统卡槽的有效天数
            if (LocalDateTime.now().isAfter(userSlot.getExpireTime())) {
                updateSlot.setExpireTime(LocalDateTime.now().plusDays(slot.getExpiration()));
            } else {
                // 如果用户卡槽expireTime未过期，则从用户卡槽expireTime开始计算加上系统卡槽的有效天数
                updateSlot.setExpireTime(userSlot.getExpireTime().plusDays(slot.getExpiration()));
            }
        } else {
            throw new ServiceException("未知操作类型");
        }
        boolean b = punchUserSlotService.updateById(updateSlot);
        if (!b) {
            throw new ServiceException("解锁失败");
        }
        return true;
    }
}